Skip to content

gh-145824: email.utils: replace AttributeError with TypeError in collapse_rfc2231_value for non-string non-3-tuple input#145825

Open
stefanzetzsche wants to merge 7 commits intopython:mainfrom
stefanzetzsche:fix/email_utils_collapse_non3_tuple
Open

gh-145824: email.utils: replace AttributeError with TypeError in collapse_rfc2231_value for non-string non-3-tuple input#145825
stefanzetzsche wants to merge 7 commits intopython:mainfrom
stefanzetzsche:fix/email_utils_collapse_non3_tuple

Conversation

@stefanzetzsche
Copy link
Contributor

@stefanzetzsche stefanzetzsche commented Mar 11, 2026

Issue

collapse_rfc2231_value falls through to unquote(value) for tuples whose length is not 3, but unquote expects a string, raising AttributeError.

Reproducer

from email.utils import collapse_rfc2231_value
collapse_rfc2231_value(('a', 'b'))  # AttributeError: 'tuple' object has no attribute 'startswith'

Fix

  1. In Lib/email/utils.py, raise TypeError for values that are neither a string nor a 3-tuple:
if not isinstance(value, tuple) or len(value) != 3:
    if not isinstance(value, str):
        raise TypeError(
            f"expected str or 3-tuple, got {type(value).__name__}"
        )
    return unquote(value)
  1. In Doc/library/email.utils.rst, change "not a tuple" to "not a 3-tuple" to match the code's actual check.

Tests

test_collapse_rfc2231_value_non_3_tuple in TestRFC2231 (Lib/test/test_email/test_email.py) verifies that:

  • Non-string, non-3-tuple values (empty tuple, 1-tuple, 2-tuple, 4-tuple, int, None) raise TypeError
  • A 3-tuple ('us-ascii', 'en', 'hello') decodes correctly
  • A plain quoted string '"hello"' passes through unquote

stefanzetzsche and others added 3 commits February 22, 2026 14:54
Passing a tuple of length != 3 fell through to unquote(value) which
calls .startswith() on the tuple, raising AttributeError. Handle
non-3-tuples explicitly before calling unquote.
@stefanzetzsche stefanzetzsche marked this pull request as ready for review March 11, 2026 14:42
@stefanzetzsche stefanzetzsche requested a review from a team as a code owner March 11, 2026 14:42
Copy link
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should do anything here. First, it's not a crash but rather a GIGO case (garbage in, garbage out). The documentation says:

For convenience, if the value passed to collapse_rfc2231_value() is not a tuple, it should be a string and it is returned unquoted.

So returning the stringification of the tuple may not necessarily be correct. Instead, a TypeError should be raised if AttributeError is too cryptic IMO.

@bedevere-app
Copy link

bedevere-app bot commented Mar 11, 2026

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Revised per reviewer feedback: instead of silently handling non-3-tuples,
raise TypeError with a clear message. Updated docs to say 'not a 3-tuple'
instead of 'not a tuple' to match the code's actual check.
@stefanzetzsche stefanzetzsche changed the title gh-145824: email.utils: collapse_rfc2231_value crashes on non-3-tuples gh-145824: email.utils: replace AttributeError with TypeError in collapse_rfc2231_value for non-string non-3-tuple input Mar 11, 2026
@stefanzetzsche
Copy link
Contributor Author

stefanzetzsche commented Mar 11, 2026

Thanks @picnixz, I have made the requested changes; please review again. See also #145824 (comment).

@stefanzetzsche stefanzetzsche requested a review from picnixz March 11, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants